package com.chinatechstar.auth.service.impl;

import com.chinatechstar.component.commons.utils.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.chinatechstar.auth.mapper.AuthMapper;
import com.chinatechstar.auth.service.AuthService;

/**
 * 用户认证授权信息的业务逻辑实现层
 *
 * @版权所有 上海至界信息科技有限公司
 */
@Service
@Transactional
public class AuthServiceImpl implements AuthService, UserDetailsService {

    @Autowired
    private AuthMapper authMapper;

    /**
     * 根据用户名查询当前用户信息
     */
    @Override
    public LinkedHashMap<String, Object> getSysUser(String username) {
        LinkedHashMap<String, Object> resultMap = new LinkedHashMap<>();
        LinkedHashMap<String, Object> sysUserMap = authMapper.getSysUser(username);
        // 获取用户Id
        String userId = (String) sysUserMap.get("id");
        // 用户所属的机构信息
        LinkedHashMap<String, String> org = authMapper.findOrgByUserId(userId);
        // 区域数据
        List<LinkedHashMap<String, String>> regions = new ArrayList<>();
        if (org != null) {
            String regionAncestors = org.get("region_ancestors");
            if (!StringUtils.isEmpty(regionAncestors)) {
                System.out.println(regionAncestors);
                List<LinkedHashMap<String, String>> list = authMapper.selectAllRegionByCodeIn(Arrays.asList(
                    regionAncestors.split(",")));
                regions.addAll(list);
            } else {
                LinkedHashMap<String, String> province = getSysRegionBy(org.get("province_code"),
                                                                        org.get("province_name"),
                                                                        "province");
                LinkedHashMap<String, String> city = getSysRegionBy(org.get("city_code"),
                                                                    org.get("city_name"),
                                                                    "city");
                LinkedHashMap<String, String> region = getSysRegionBy(org.get("region_code"),
                                                                      org.get("region_name"),
                                                                      "district");

                regions.add(province);
                regions.add(city);
                regions.add(region);
            }
        }

        Iterator<Entry<String, Object>> iterator = sysUserMap
            .entrySet()
            .iterator();
        LinkedHashMap<String, Object> regionMap = new LinkedHashMap<>();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> entry = iterator.next();
            String key = entry.getKey();
            Object value = entry.getValue();
            if ("provinceRegionCode".equals(key) || "provinceRegionName".equals(key)
                || "cityRegionCode".equals(key) || "cityRegionName".equals(key)) {
                regionMap.put(key, value);
                continue;
            }
            if ("roles".equals(key)) {
                resultMap.put(key,
                              String
                                  .valueOf(value)
                                  .split(","));
            } else {
                resultMap.put(key, value);
            }
        }
        resultMap.put("geographic", getGeographic(regionMap));
        resultMap.put("regions", regions);
        return resultMap;
    }

    private LinkedHashMap<String, String> getSysRegionBy(String code,
                                                         String name,
                                                         String regionType) {
        LinkedHashMap<String, String> region = new LinkedHashMap<>();
        region.put("region_name", name);
        region.put("region_code", code);
        region.put("region_type", regionType);
        return region;
    }

    /**
     * 根据区域参数转为界面区域信息
     *
     * @param regionMap 区域参数
     * @return
     */
    private LinkedHashMap<String, Object> getGeographic(LinkedHashMap<String, Object> regionMap) {
        LinkedHashMap<String, Object> geographicMap = new LinkedHashMap<>();
        LinkedHashMap<String, Object> provinceMap = new LinkedHashMap<>();
        provinceMap.put("key", regionMap.get("provinceRegionCode"));
        provinceMap.put("label", regionMap.get("provinceRegionName"));
        LinkedHashMap<String, Object> cityMap = new LinkedHashMap<>();
        cityMap.put("key", regionMap.get("cityRegionCode"));
        cityMap.put("label", regionMap.get("cityRegionName"));
        geographicMap.put("province", provinceMap);
        geographicMap.put("city", cityMap);
        return geographicMap;
    }

    /**
     * 根据用户名查询用户详细信息
     */
    @Override
    public UserDetails loadUserByUsername(String username) {
        LinkedHashMap<String, String> user = authMapper.getSysUserByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException(String.format("找不到此用户名%s。", username));
        }
        List<String> roleCodeList = authMapper.queryRoleCodeByUsername(username);
        return new User(username,
                        user.get("PASSWORD"),
                        AuthorityUtils.createAuthorityList(roleCodeList.toArray(new String[]{})));
    }

}
